package com.lge.pitchingcoins.util.sessions;

import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.lge.pitchingcoins.util.PitchingCoinsLog;




/**
 * @author jungyeon1.kim
 * 
 */
public class GameCmdManager {
    public static final String TAG = "GameCmdManager";
    private static BlockingQueue<GameCmdBase> mCmdQueue = new ArrayBlockingQueue<GameCmdBase>(
            100);

    private static GameCmdSendDTO rcv_message;
    
    /**
     * SingletonHolder
     */
    private static class SingletonHolder {
        public static final GameCmdManager INSTANCE = new GameCmdManager();
    }

    public static GameCmdManager getInstance() {
        return SingletonHolder.INSTANCE;
    }

    public abstract class GameCmdBase {
        protected String mOwner;
        protected String mEventName;

        public GameCmdBase() {
            mOwner = "";
        }

        public abstract String toJSONString();
    }

    public class GameCmdSendDTO extends GameCmdBase {

        private String userName = "";
        private float mX = 0;
        private float mY = 0;
        private float mZ = 0;
        private int force;

        public GameCmdSendDTO(String userName, float x, float y, float z,
                int force) {
            PitchingCoinsLog.d("GameCmdSendDTO");

            this.userName = userName;
            mX = x;
            mY = y;
            mZ = z;

            this.force = force;
        }

        public GameCmdSendDTO(String userName, float x, float y, float z,
                int force, int magnification) {
            this.userName = userName;
            PitchingCoinsLog.d("GameCmdSendDTO_parse");
            mX = x;
            mY = y;
            mZ = z;

            this.force = force;
        }
        
        
        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }

        public float getX() {
            return mX;
        }

        public void setX(float mX) {
            this.mX = mX;
        }

        public float getY() {
            return mY;
        }

        public void setY(float mY) {
            this.mY = mY;
        }

        public float getZ() {
            return mZ;
        }

        public void setZ(float mZ) {
            this.mZ = mZ;
        }

        public int getForce() {
            return force;
        }

        public void setForce(int force) {
            this.force = force;
        }
        
        

        @Override
        public String toJSONString() {
            return sendToJSONString();
        }

        private String sendToJSONString() {
            String sendSONStr = "";
            try {
                sendSONStr = "{\"D\":[" + userName + "," + mX + "," + mY + ","
                        + mZ + "," + force + "]" + "}";
                return sendSONStr;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";

        }
    }

    public static GameCmdSendDTO parse(String data, GameCmdManager cmdManager) {
        PitchingCoinsLog.d("parse");

        if (data != null && cmdManager != null) {
            try {
                JSONObject obj = new JSONObject(data);
                JSONArray ar = obj.getJSONArray("D");

                ar = obj.getJSONArray("D");
                String userName = ar.getString(0);
                float x = (float)ar.getDouble(1);
                float y = (float)ar.getInt(2);
                float z = (float)ar.getInt(3);
                int force = ar.getInt(4);

                PitchingCoinsLog.d("userName : " + userName);
                PitchingCoinsLog.d("x : " + x);
                PitchingCoinsLog.d("y : " + y);
                PitchingCoinsLog.d("z : " + z);
                PitchingCoinsLog.d("force : " + force);

                rcv_message = cmdManager.new GameCmdSendDTO(
                        userName, x, y, z, force, 1);

                //            list.add(rcv_message);
                // for (int i = 0; i < ar.length(); i++) {
                // parseOneObject(ar.getJSONObject(i), list, cmdManager);
                // }
            } catch (JSONException e) {
                e.printStackTrace();
                return null;
            }

            return rcv_message;
        } else {
            PitchingCoinsLog.d(TAG + ": data = " + data + ", cmdManager =" + cmdManager);
            return null;
        }
    }

    //	private static boolean parseOneObject(JSONObject obj,
    //			ArrayList<GameCmdBase> list, GameCmdManager cmdManager) {
    //		PitchingCoinsLog.d("parseOneObject");
    //		PitchingCoinsLog.d("obj is " + obj);
    //		if (obj == null || list == null || cmdManager == null) {
    //			PitchingCoinsLog.d(TAG, "obj = " + obj + ", list = " + list
    //					+ ", cmdManager =" + cmdManager);
    //			return false;
    //		}
    //
    //		JSONArray ar = null;
    //		try {
    //			ar = obj.getJSONArray("D");
    //			String userName = ar.getString(0);
    //			float x = (float) ar.getDouble(1);
    //			float y = (float) ar.getInt(2);
    //			float z = (float) ar.getInt(3);
    //			int force = ar.getInt(4);
    //
    //			PitchingCoinsLog.d("userName : " + userName);
    //			PitchingCoinsLog.d("x : " + x);
    //			PitchingCoinsLog.d("y : " + y);
    //			PitchingCoinsLog.d("z : " + z);
    //			PitchingCoinsLog.d("force : " + force);
    //
    //			GameCmdSendDTO rcv_message = cmdManager.new GameCmdSendDTO(
    //					userName, x, y, z, force, 1);
    //
    //			list.add(rcv_message);
    //		} catch (JSONException e) {
    //			e.printStackTrace();
    //			return false;
    //		}
    //
    //		return true;
    //	}

    public static void pumpUp(ArrayList<GameCmdBase> list) {
        PitchingCoinsLog.d("pumpUp");
        try {
            // while (!list.isEmpty()) {
            // GameCmdBase cmd = list.remove(0);
            // mCmdQueue.put(cmd);
            // }

            while (true) {
                GameCmdBase cmd = list.remove(0);
                mCmdQueue.put(cmd);
                if (!list.isEmpty()) {
                    break;
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public BlockingQueue<GameCmdBase> getCmdQueue() {
        return mCmdQueue;
    }

}
